import json
import re
import os
from bs4 import BeautifulSoup
import autogen
from autogen.retrieve_utils import create_vector_db_from_dir, query_vector_db
import chromadb.utils.embedding_functions as ef
from prompts import *
from rules import *
from config import llm_config_path, seed, use_cache, temperature, embedding_model_path, knowledge_dir, db_path, is_silent


template_pattern = re.compile(r"<template>(.*?)</template>", re.DOTALL)
script_pattern = re.compile(r"<script>(.*?)</script>", re.DOTALL)
style_pattern = re.compile(r"<style[^>]*>(.*?)</style>", re.DOTALL)
vue_import_pattern = re.compile(r"""(import (\w+) from ["']([\./\w+]*)["'];?)\n""")
vue_v_model_pattern = re.compile(r"""(<input[^>]*(v-model="([^"]*)").*?(?:\/>|<\/input>))""", re.DOTALL)
vue_class_bind_pattern = re.compile(r"""(<[^>]*?((?:v-bind)?\:class=(["'])((?:(?:\[)[^\]]*?\])|(?:(?:\{)[^\}]*?\}))\3)[^>]*>)""", re.DOTALL)
style_unit_pattern = re.compile(r"""((\d+)(?:em|rem|vw|vh))""")
style_display_pattern = re.compile(r"""display:\s*([a-z-]+);""")
response_code_section_pattern = re.compile("\[\[code_section\]\](.*)\[\[\/code_section\]\]", re.DOTALL)
response_judge_pattern = re.compile("\[\[judge\]\](.*)\[\[\/judge\]\]", re.DOTALL)
response_action_pattern = re.compile("\[\[action\]\](.*)\[\[\/action\]\]", re.DOTALL)

config_list = autogen.config_list_from_json(env_or_file=llm_config_path)
small_llm_config = {
    "config_list": [config_list[0]],
    "seed": seed,
    "use_cache": use_cache,
    "temperature": temperature
}
large_llm_config = {
    "config_list": [config_list[1]],
    "seed": seed,
    "use_cache": use_cache,
    "temperature": temperature
}
glm4_llm_config = {
    "config_list": [config_list[2]],
    "seed": seed,
    "use_cache": use_cache,
    "temperature": temperature
}

embedding_function = ef.SentenceTransformerEmbeddingFunction(model_name=embedding_model_path)

def gen_project_description(projectName, description):
    message = """
Please name this project and write a brief description based on the readme file and project dir name.
The description should only be related to the functionality.
For name composed of multiple single-word groups, you should use '-' to connect them.

project dir name:
%s
readme file content:
%s

your response should follow this format:
{
    "projectName": "project name is here",
    "description": "description is here"
}

example:
{
    "projectName": "hello-world",
    "description": "xxx"
}
""" % (projectName, description)
    response = autogen.oai.ChatCompletion.create(
        messages=[
            {"role": "system", "content": "you are a helpful AI assistant. Your response should follow JSON format."},
            {"role": "user", "content": message}
        ],
        config_list=small_llm_config["config_list"]
    )
    responseText = response.choices[0]["message"]["content"]
    print(responseText)
    return json.loads(responseText)


class Vue2BlueConverter:
    """
    Vue Convert Manager
    """

    blueos_component = ["a", "image", "marquee", "progess", "arc-text", "barcode", "qrcode", "canvas", 
                    "input", "label", "picker", "slider", "switch", "artboard", "list", "list-item", "stack", 
                    "swiper", "scroll", "drawer", "draw-navigation", "cellular-list", "svg-container", "image-animator", 
                    "animated-vector", "vw-alert", "vw-buttom", "vw-empty", "vw-icon", "vw-slide", "vw-title", "vw-list",
                    "vw-list-item", "vw-loading"]

    def __init__(self, file_content):
        # 文件信息
        self.vue_file_content = file_content
        vue_template_match = template_pattern.search(self.vue_file_content)
        vue_script_match = script_pattern.search(self.vue_file_content)
        vue_style_match = style_pattern.search(self.vue_file_content)
        if not vue_template_match or not vue_script_match:
            raise ValueError("Vue文件格式错误")
        self.vue_template = vue_template_match.group(0)
        self.vue_script = vue_script_match.group(0)
        self.vue_style = vue_style_match.group(0) if vue_style_match else ""
        self.global_memory = {}
        
            
        # 知识库信息
        self.db_client = None
        # self.init_embedding_db()
        # 
        
        # Agent信息
        self.user_proxy = None
        self.actor_agent = None
        self.judge_agent = None
        self.retrieve_agent = None
        self.reflection_agent = None
        self.init_agents()

        # 流程控制
        self.is_next = False
        self.is_done = False
        self.is_stop = False
        # 转换过程
        self.template_section = self.vue_template
        self.script_section = self.vue_script
        self.style_section = self.vue_style

    def set_global_memory(self, key, value):
        self.global_memory[key] = value


    def init_agents(self):
        self.user_proxy = autogen.UserProxyAgent(
            "Admin",
            is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
            human_input_mode="TERMINATE",
            code_execution_config=False
        )
        self.assistant_agent = autogen.AssistantAgent(
            "BlueOS-Converter",
            system_message=assistant_agent_system_prompt,
            llm_config=small_llm_config,
        )
        self.actor_agent = autogen.AssistantAgent(
            "BlueOS-Coder",
            system_message=blueos_agent_system_prompt,
            llm_config=small_llm_config,
        )
        self.judge_agent = autogen.AssistantAgent(
            "BlueOS-Judge",
            system_message=judge_agent_system_prompt,
            llm_config=small_llm_config
        )
        self.retrieve_agent = autogen.AssistantAgent(
            "Retrieve-Assistant",
            system_message=retrieve_agent_system_prompt,
            llm_config=small_llm_config
        )
        self.evaluator_agent = autogen.AssistantAgent(
            "BlueOS-Evaluator",
            system_message=evaluator_agent_system_prompt,
            llm_config=small_llm_config
        )
        self.reflection_agent = autogen.AssistantAgent(
            "BlueOS-Reflection",
            system_message=reflection_agent_system_prompt,
            llm_config=small_llm_config
        )
        self.general_json_agent = autogen.AssistantAgent(
            "General-Jsoner",
            system_message=general_json_agent_system_prompt,
            llm_config=small_llm_config
        )

    def init_embedding_db(self):
        print("----------初始化向量数据库----------")
        self.db_client = create_vector_db_from_dir(
            dir_path=knowledge_dir,
            collection_name="knowledge",
            max_tokens=1000,
            must_break_at_empty_line=False,
            db_path=db_path,
            embedding_function=embedding_function,
            get_or_create=True,
        )

    def query_knowledge(self, text, search_string=""):
        if not self.db_client:
            self.init_embedding_db()
        results = query_vector_db(
            query_texts=[text],
            n_results=1,
            client=self.db_client,
            search_string=search_string,
            collection_name="knowledge"
        )
        return results

    def _convert_by_agent(self, code_section, rules, knowledge="", max_round=3, rebuttal=False, agent=None):
        """
        通过Agent进行转换
        """
        # TODO: RAG查询知识库, 由于文档知识较少，暂时不使用。
        # 目前仅使用规则库，及在不同的转换步骤，使用不用的转换规则，转换规则可以是自然语言、亦可以是python代码实现。
        # 目前Memory通过对话上下文实现，后续可以通过数据库存储或文档，用于RAG增强。
        if agent is None:
            action_agent = self.actor_agent
        else:
            action_agent = agent

        message = code_section + "\nRules: \n" + rules
        if knowledge:
            message += f"Documents:\n{knowledge}"

        actor_round = 0
        # 清空Memory
        action_agent.clear_history()
        self.user_proxy.clear_history()
        # actor与judge交互
        while actor_round < max_round:
            self.user_proxy.send(message, action_agent, request_reply=True, silent=is_silent)
            actor_response = action_agent.last_message()["content"]
            template_section_match = template_pattern.search(actor_response)
            script_section_match = script_pattern.search(actor_response)
            style_section_match = style_pattern.search(actor_response)
            if template_section_match:
                template_section = template_section_match.group(0).strip()
                # 针对于特定prompt的异常处理
                if "Your template code here" in template_section:
                    template_section = ""
                if template_section_match.group(1).strip() == "":
                    template_section = ""
                if "your template here" in template_section:
                    template_section = ""
            else:
                template_section = ""
            if script_section_match:
                script_section = script_pattern.search(actor_response).group(0).strip()
            else:
                script_section = ""
            if style_section_match:
                style_section = style_pattern.search(actor_response).group(0).strip()
                if "style here" in style_section:
                    style_section = ""
            else:
                style_section = ""

            if not rebuttal:
                break

            if template_section == "" and script_section == "" and style_section == "":
                break

            # 与评判者交互
            action_section = ""
            action_section_match = response_action_pattern.search(actor_response)
            if action_section_match:
                action_section = action_section_match.group(1).strip()

            if actor_round == 0:
                first_judge_message = f"""
Before Transformation:
{code_section}
Transformation Rules:
{rules}
"""
                self.user_proxy.send(message=first_judge_message, recipient=self.judge_agent, silent=is_silent)

            judge_message = f"""
Actions Taken:
{action_section}
After Transformation Results:
{template_section}
{script_section}
{style_section}
"""
            self.user_proxy.send(message=judge_message, recipient=self.judge_agent, request_reply=True, silent=is_silent)
            judge_response = self.judge_agent.last_message()["content"]
            if judge_response.strip().endswith("TERMINATE"):
                break
            rebutal_content = response_judge_pattern.search(judge_response).group(1).strip()
            message = f"""
{template_section}
{script_section}
{style_section}
Documents:
{knowledge}
Suggestion:
{rebutal_content}
"""
            actor_round += 1
        return (
            template_section if template_section else self.template_section,
            script_section if script_section else self.script_section,
            style_section if style_section else self.style_section
        )

    def convert_component(self):
        """
        组件转换

        负责转换不兼容的组件、数据单向绑定、setInterval的this指向问题
        """
        # 查询涉及到的组件
        component_list = set(c.name for c in BeautifulSoup(self.vue_template, "html.parser").find_all())
        component_list = [c for c in component_list if c in self.blueos_component]
        print("涉及组件列表：", component_list)

        code_section = f"""
{self.template_section}
{self.script_section}
{self.style_section}
"""
        # 查询知识库
        knowledge = ""
        
        return self._convert_by_agent(code_section, component_rules, knowledge, rebuttal=False)

    def convert_import(self):
        """
        组件引入转换，应该区分js引入
        使用代码进行硬转换
        """
        # 应用当前所拥有的页面
        # ["/page/index", "/page/demo"]
        import_components_list = []
        pages = self.global_memory.get("pages", [])
        cur_filepath = self.global_memory.get("filepath", "")
        vue_components = self.global_memory.get("vue_components", {})
        matchs = vue_import_pattern.findall(self.script_section)

        if len(matchs) == 0:
            # 无import
            return self.template_section, self.script_section, self.style_section
        
        script_section = self.script_section
        for import_statement, component, component_path in matchs:
            if component not in vue_components:
                continue
            # 去除.vue后缀以及相对路径
            component_path = component_path.replace(".vue", "").replace(".", "")
            for page in pages:
                if component_path.lower() in page.lower():
                    component_path = page
                    # 采用相对路径
                    # 去除index.ux
                    component_path = "/".join(component_path.strip("src").split("/")[:-1])
                    cur_filepath = "/".join(cur_filepath.strip("src").split("/")[:-1])
                    rel_component_path = os.path.relpath(component_path, cur_filepath).replace("\\", "/")

            import_template = f"""<import name="{component}" src="{rel_component_path}"></import>"""
            import_components_list.append(import_template)
            script_section = script_section.replace(import_statement, "")
        
        template_section = "\n".join(set(import_components_list)) + "\n" + self.template_section
        return template_section, script_section, self.style_section

    def convert_computed(self):
        """
        计算属性转换
        """
        extra_computed_rules = ""
        computed_func_list = []
        vue_computed_methods = self.global_memory.get("vue_computed", {})
        if not bool(vue_computed_methods):
            # 无计算属性
            return self.template_section, self.script_section, self.style_section

        vue_methods = self.global_memory.get("vue_methods", {})
        for computed_name, computed_info in vue_computed_methods.items():
            func_name = "updateComputed" + computed_name[0].upper() + computed_name[1:]
            func_body = computed_info["body"].replace("function", "").strip()
            func_params = ", ".join(computed_info["params"])

            func_text = "%s(%s) {\n%s\n}" % (func_name, func_params, func_body)
            computed_func = {
                "data": computed_name,
                "func_name": func_name,
                "func": func_text,
                "vars": computed_info["vars"]
            }
            computed_func_list.append(computed_func)

            extra_computed_rules += f"""请你定义变量 {computed_func["data"]}，并初始化值为null\n"""
            extra_computed_rules += f"""请你定义方法 {computed_func["func"]}\n"""
            extra_computed_rules += f"""请你在`onInit`方法中调用方法{computed_func["func_name"]}\n"""
            extra_computed_rules += "自增（var++）或自减(var--)运算也会改变变量的值，也需要调用对应的updateComputed更新方法。\n"
            # 查找每个方法中的变量以确定依赖关系
            for method_name, method_info in vue_methods.items():
                computed_vars_set = set(computed_func["vars"])
                method_vars_set = set(method_info["vars"])
                # 计算交集
                vars_intersection = computed_vars_set & method_vars_set
                # 计算属性转换后的方法是无参数的
                extra_computed_rules += f"""在方法{method_name}中，当变量{", ".join(vars_intersection)}的值发生改变之后(包括自增++和自减--运算)，插入调用方法this.{computed_func["func_name"]}的代码语句\n"""
        extra_computed_rules += """
例如：在方法test中，当变量testVar值发生变化时，在其改变之后插入调用方法updateComputedTest
test() {
    this.testVar++;
    this.updateComputedTest();
}
"""
        extra_computed_rules += "请你移除computed下的内容。\n"
        extra_computed_rules += "当你插入调用方法语句时，不应该覆盖原有的代码。"
        self.set_global_memory("computed_func_list", computed_func_list)
        
        return self._convert_by_agent(self.script_section, extra_computed_rules, rebuttal=True)
        
    def convert_v_model(self):
        """
        双向绑定转换
        """
        extra_v_model_message = ""
        matchs = vue_v_model_pattern.findall(self.vue_template)

        if len(matchs) == 0:
            return self.template_section, self.script_section, self.style_section

        for match in matchs:
            input_component = match[0]
            v_model = match[1]
            var = match[2]

            change_method_name = "updateVModel" + var[0].upper() + var[1:]
            change_method_body = """
        %s(event) {
            this.%s = event.text
        }""" % (change_method_name, var)
            
            new_input_component = input_component.replace(v_model, """value="{{ %s }}" onchange="%s" """ % (var, change_method_name))
            extra_v_model_message += f"""请你将{input_component}替换为{new_input_component}\n"""
            extra_v_model_message += f"""请你定义方法{change_method_body}\n"""

        code_section = self.template_section + "\n" + self.script_section
        return self._convert_by_agent(code_section, extra_v_model_message, rebuttal=False)

    def convert_class_bind(self):
        """
        动态类绑定转换
        """
        vue_data = self.global_memory.get("vue_data", {})
        vue_methods = self.global_memory.get("vue_methods", {})
        extra_class_bind_message = ""

        matchs = vue_class_bind_pattern.findall(self.template_section)

        if len(matchs) == 0:
            # 无动态类绑定
            return self.template_section, self.script_section, self.style_section
        
        for match in matchs:
            class_bind_func_list = match[3].strip("{}[]").split(",")
            # 函数参数
            params = set()
            
            class_bind_dict = dict()
            for class_bind_func in class_bind_func_list:
                class_bind_func = class_bind_func.strip("{}[]")
                if ":" not in class_bind_func:
                    continue
                class_name = class_bind_func.split(":")[0].strip()
                bind_logic = class_bind_func.split(":")[1].strip()
                class_name = class_name.replace("'", "\"")
                if not (class_name.startswith('"') and class_name.endswith('"')):
                    class_name = f"\"{class_name.strip()}\""
                # 判断条件
                condition = ""
                # 是否是多个判断条件共同作用
                is_multi_condition = False
                if "&&" in bind_logic or "&" in bind_logic or "|" in bind_logic or "||" in bind_logic:
                    is_multi_condition = True
                if is_multi_condition:
                    condition_list = []
                    operator_list = re.findall(r"&&|\|\||&|\|", bind_logic)
                else:
                    temp_condition = bind_logic

                # 正则匹配判断条件
                func_matchs = re.findall(r"""(["']?[\w\.]+["']?)(?:\s*(\([^)]*\)))?""", bind_logic)
                # assert len(operators) == len(func_matchs) - 1

                for func_match in func_matchs:
                    func_name = func_match[0]
                    func_params = func_match[1]
                    if "(" in func_params and ")" in func_params:
                        # 理应是一个方法
                        if is_multi_condition:
                            condition_list.append(f"this.{func_name}{func_params}")
                        else:
                            temp_condition = re.sub(rf"{func_name}\s*{func_params}", f"this.{func_name}{func_params}", temp_condition)
                        if func_params.strip("()"):
                            for p in func_params.strip("()").split(","):
                                if p not in vue_data:
                                    params.add(p)
                    else:
                        if func_name in vue_methods:
                            # 无传参方法
                            if is_multi_condition:
                                condition_list.append(f"this.{func_name}{func_params}")
                            else:
                                temp_condition = temp_condition.replace(f"{func_name}", f"this.{func_name}")
                        else:
                            # 理应是变量或表达式
                            if "." in func_name and func_name.split(".")[0] != "this":
                                # 对象的属性
                                func_name = func_name.split(".")[0]
                            if (
                                (func_name.startswith("\"") and func_name.endswith("\"")) or
                                (func_name.startswith("'") and func_name.endswith("'"))
                            ):
                                # 若是字符串
                                continue
                            if func_name in vue_data:
                                if is_multi_condition:
                                    condition_list.append(f"this.{func_name}{func_params}")
                                else:
                                    temp_condition = temp_condition.replace(f"{func_name}", f"this.{func_name}")
                            else:
                                params.add(func_name)
                if is_multi_condition:
                    for i in range(len(operator_list)):
                        condition += f"{condition_list[i]} {operator_list[i]} "
                    condition += condition_list[-1]
                else:
                    condition = temp_condition
                class_bind_dict[class_name] = condition

            # 定义获取类的方法
            def format_class_name(class_name):
                class_name = class_name.strip("\"").replace("-", "").replace("_", "")
                return class_name[0].upper() + class_name[1:]
            # 方法名
            total_class_name_list = class_bind_dict.keys()
            total_class_name_list = list(map(format_class_name, total_class_name_list))
            class_bind_func_name = "getClassName" + "".join(total_class_name_list)
            class_bind_func_params = ", ".join(params)
            class_bind_func_body_condition = ""
            for class_name, bind_logic in class_bind_dict.items():
                class_bind_func_body_condition += """
        if (%s) {
            class_name_list.push(%s)
        }
        """ % (bind_logic, class_name)
            class_bind_func = """
        %s (%s) {
        let class_name_list = []
            %s
        return class_name_list.join(" ")
        }    
        """ % (class_bind_func_name, class_bind_func_params, class_bind_func_body_condition)

            vue_class_bidn_component = match[0]
            new_class_bind_component = vue_class_bidn_component.replace(match[1], "class=\"{{ %s }}\"" % (f"{class_bind_func_name}({class_bind_func_params})"))
            extra_class_bind_message += f"请你将{vue_class_bidn_component}替换为{new_class_bind_component}\n"
            extra_class_bind_message += f"请你定义方法{class_bind_func}\n"


        # 利用Agent执行转换
        code_section = self.template_section + "\n" + self.script_section
        return self._convert_by_agent(code_section, extra_class_bind_message, rebuttal=False)

    # 规则库
    def convert_watch(self):
        """
        转换watch属性
        """
        extra_watch_message = ""
        vue_method = self.global_memory.get("vue_methods", {})
        vue_watch = self.global_memory.get("vue_watch", {})
        if not bool(vue_watch):
            # 无watch属性
            return self.template_section, self.script_section, self.style_section

        for data_name, data_info in vue_watch.items():
            # 遍历所有方法，检查是否有方法会改变这个向量
            func_name = "updateWatch" + data_name[0].upper() + data_name[1:]
            func_params = ", ".join(data_info["params"])
            func = """
%s(%s) {\n%s\n}""" % (func_name, func_params, data_info["handler"])
            extra_watch_message += f"请你定义方法{func}\n"
            for method_name, method_info in vue_method.items():
                if data_name in method_info["vars"]:
                    extra_watch_message += f"""在方法{method_name}中，如果{data_name}的值将发生改变，在其改变前调用方法{func_name}然后再改变{data_name}值，{func_name}方法的参数为{data_name}修改前的值和修改后的值\n"""
        extra_watch_message += "请你移除watch下的内容。\n"
        extra_watch_message += "当你插入调用方法语句时，不应该覆盖原有的代码。"

        return self._convert_by_agent(self.script_section, extra_watch_message, rebuttal=False)
    
    def convert_style(self):
        """
        转换style标签
        """
        # 字号转换，除px之外全部替换为* @size-factor
        style_section = self.style_section

        if style_section.strip("<style></style>").strip() == "":
            # 没有样式代码，返回默认样式
            print("样式为空")
            return self.template_section, self.script_section, self.style_section
        
        matchs = style_unit_pattern.findall(self.style_section)
        cur_filepath = self.global_memory.get("filepath", "")
        for match in matchs:
            style_section = style_section.replace(match[0], f"{match[1]}*@size-factor")
        # display
        matchs = style_display_pattern.findall(style_section)
        matchs = set(matchs)
        for match in matchs:
            style_section = style_section.replace(match, "flex")
        style_less_filepath = "src/assets/styles/style.less"
        # 将hover替换为active
        style_section = style_section.replace(":hover", ":active")
        # 去除index.ux
        cur_filepath = "/".join(cur_filepath.split("/")[:-1])
        print("当前文件路径："+cur_filepath)
        rel_style_less_path = os.path.relpath(style_less_filepath, cur_filepath).replace("\\", "/")
        extra_style_message = f"""
2. 请你引入默认样式：@import '{rel_style_less_path}';
"""

        return self._convert_by_agent(style_section, general_style_rules+extra_style_message, rebuttal=False)

        # return self._convert_by_agent(self.style_section, general_style_rules, rebuttal=False)

    def init_global_memory(self):
        """
        初始化全局记忆，记录转换前有哪些方法、计算属性、watch属性
        采用JSON-Agent提取
        """
        json_rules = ""
        json_result = {}
        # 是否提取添加方法和参数
        method_param_flag = False

        if "data:" in self.script_section or "data()" in self.script_section:
            json_rules += data_json_rules

        if "computed:" in self.script_section:
            json_rules += computed_json_rules
            method_param_flag = True

        if "methods:" in self.script_section:
            json_rules += methods_json_rules
            method_param_flag = True

        if "watch:" in self.script_section:
            json_rules += watch_json_rules
            method_param_flag = True

        if "components:" in self.script_section:
            json_rules += import_component_json_rules


        if json_rules.strip() == "":
            # 当前页面无计算属性、watch属性、方法定义
            return
        
        if method_param_flag:
            json_rules += """
你需要检查每个方法依赖哪些位于data中的变量，将其存储在varbales_array数组中。

你需要检查每个方法的参数，将其存储在method_params_array数组中，若参数含有默认值，请指出。
例如：参数param1的默认值为value1, 应记为param1=value1
"""
        
        json_agent_message = """
%s

%s

你没有被要求时，不能随便修改方法和变量。
""" % (self.script_section, json_rules)
        error_message = ""
        error_count = 0
        while error_count < 3:
            json_agent_message += error_message
            self.user_proxy.send(json_agent_message, recipient=self.general_json_agent, request_reply=True, silent=is_silent)
            json_response = self.general_json_agent.last_message()["content"]
            if json_response.startswith("`") :
                # 使用markdown回答
                json_response = json_response.strip("```json")
            try:
                json_result = json.loads(json_response)
                break
            except json.JSONDecodeError as e:
                error_count += 1
                error_message = f"请你确保你的输出是一个JSON对象"
        self.set_global_memory("vue_computed", json_result.get("computed", {}))
        self.set_global_memory("vue_methods", json_result.get("methods", {}))
        self.set_global_memory("vue_watch", json_result.get("watch", {}))
        self.set_global_memory("vue_data", json_result.get("data", {}))
        self.set_global_memory("vue_components", json_result.get("components", {}))

    def pre_process(self):
        code_section = f"""
{self.template_section}

{self.script_section}
"""
        template_section, script_section, style_section = (
            self._convert_by_agent(code_section, preprocess_rules, rebuttal=False, agent=self.assistant_agent)
        )
        self.template_section = template_section
        self.script_section = script_section

    def done(self):
        self.is_done = True

    def stop(self):
        self.is_stop = True

    def error_feedback(self, error_list):
        error_message = ""
        # Evaluator Agent，在这里判断哪些错误需要进行反思，这里暂不适用Agent而采用使用python实现
        # 报错过于复杂，暂未编写规则进行处理。
        for error in error_list:
            error_message_item = error.message
            if "未识别的标签名" in error_message_item:
                match = re.search("'(\w+)'", error_message_item)
                if match:
                    component_name = match.group(1)
                    component_name = component_name[0].upper() + component_name[1:]
                    # 获取当前页面
                    pages = self.global_memory.get("pages", [])
                    # 查询component_name是否在pages中
                    for page in pages:
                        if component_name in page:
                            # 组件存在
                            continue
            if error_message_item.startswith("Cannot find module"):
                continue
            error_message += error_message_item + "\n"
        if error_message.strip() == "":
            print("无需错误反馈")
            return f"{self.template_section}\n\n{self.script_section}\n\n{self.style_section}"
        evaluator_message = f"""
错误提示：
{error_message}
{error_message_rules}
"""
        self.user_proxy.send(evaluator_message, recipient=self.evaluator_agent, request_reply=True, silent=is_silent)
        evaluator_response = self.evaluator_agent.last_message()["content"]
        reflection_message = f"""
BlueOS 组件代码：
{self.template_section}
{self.script_section}
{self.style_section}
错误提示：
{evaluator_response}
"""
        self.user_proxy.send(reflection_message, recipient=self.reflection_agent, request_reply=True, silent=is_silent)
        reflection_response = self.reflection_agent.last_message()["content"]

        code_section = f"""
BlueOS 组件代码：
{self.template_section}
{self.script_section}
{self.style_section}
"""
        rules = f"""
错误提示：
{evaluator_response}
自我反思：
{reflection_response}
"""

        template_section, script_section, style_section = self._convert_by_agent(code_section, rules, rebuttal=False)
        self.template_section = template_section
        self.script_section = script_section
        self.style_section = style_section
        return f"{template_section}\n\n{script_section}\n\n{style_section}"

    def start(self):
        self.pre_process()
        self.init_global_memory()
        # 逐步转换
        steps = [
            ("computed", self.convert_computed),
            ("class-bind", self.convert_class_bind),
            ("v-model", self.convert_v_model),
            ("watch", self.convert_watch),
            ("component", self.convert_component),
            ("import", self.convert_import),
            ("style", self.convert_style),
        ]
        for step_name, step_func in steps:

            if self.is_stop:
                return {
                    "start": False,
                    "content": "",
                    "process": "interrupt"
                }

            yield {
                "start": True,
                "content": "",
                "process": step_name
            }

            template_section, script_section, style_section = step_func()
            self.template_section = template_section
            self.script_section = script_section
            self.style_section = style_section
            result = f"{template_section}\n\n{script_section}\n\n{style_section}"

            yield {
                "start": False,
                "content": result,
                "process": step_name
            }